﻿using System;
using System.Data.Entity.Validation;
using System.Diagnostics;
using System.Linq;
using System.Text;
using NUnit.Framework;
using QuickPrompt.DataAccess;
using QuickPrompt.DomainModel.Identity;
using RedandBlue.Common.Authorization;
using RedandBlue.RepositoryPattern.DataContext;
using RedandBlue.RepositoryPattern.EF6;
using RedandBlue.RepositoryPattern.Infrastructure;
using RedandBlue.RepositoryPattern.Repositories;
using RedandBlue.RepositoryPattern.UnitOfWork;

namespace QuickPrompt.Test.IntegrationTests
{
    public class UserRepositoryTest
    {
        public TestContext TestContext { get; set; }

        [SetUp]
        public void Initialize()
        {
            //Utility.CreateSeededTestDatabase();
        }

        [TearDown]
        public void Cleanup()
        {
        }

        [Test(Description = "Insert Users")]
        [TestCase("Harsha", "TestEight$1", "TestEight$2", "TestEight$3")]
        public void InsertUsers(string searchName, string pwd1, string pwd2, string pwd3)
        {
            Password password = new Password();
            using (IDataContextAsync context = new QuickPromptContext())
            using (IUnitOfWorkAsync unitOfWork = new UnitOfWork(context))
            {
                IRepositoryAsync<User> userRepository = new Repository<User>(context, unitOfWork);
                string salt = password.GenerateSalt();
                string passwordHash = password.EncodeToHash(pwd1, salt);
                var user1 = new User
                {
                        //UserId = 1,
                        //UserGuid = Guid.NewGuid(),
                        UserName = "hbopuri",
                        FirstName = "Harsha",
                        LastName = "Bopuri",
                        Locked = false,
                        IsDeleted = false,
                        IsAdmin = 1,
                        LastUpdatedUtc = DateTime.UtcNow,
                        DateCreatedUtc = DateTime.UtcNow,
                        UpdatedByUserId = 0,
                        IsActive = false,
                        Password = pwd1,
                        PasswordSalt = salt,
                        PasswordHash = passwordHash,
                        ObjectState = ObjectState.Added
                    };

                passwordHash = password.EncodeToHash(pwd1, salt);
                var user2 = new User
                {
                        //UserId = 2,
                        //UserGuid = Guid.NewGuid(),
                        UserName = "user2",
                        FirstName = "Two F Name",
                        LastName = "Last Name",
                        Locked = false,
                        IsDeleted = false,
                        IsAdmin = 1,
                        LastUpdatedUtc = DateTime.UtcNow,
                        DateCreatedUtc = DateTime.UtcNow,
                        UpdatedByUserId = 0,
                        IsActive = false,
                        Password = pwd1,
                        PasswordSalt = salt,
                        PasswordHash = passwordHash,
                        ObjectState = ObjectState.Added
                    };

                passwordHash = password.EncodeToHash(pwd1, salt);
                var user3 = new User
                {
                        //UserId = 3,
                        //UserGuid = Guid.NewGuid(),
                        UserName = "user3",
                        FirstName = "three First Name",
                        LastName = "Last Name",
                        Locked = false,
                        IsDeleted = false,
                        IsAdmin = 1,
                        LastUpdatedUtc = DateTime.UtcNow,
                        DateCreatedUtc = DateTime.UtcNow,
                        UpdatedByUserId = 0,
                        IsActive = false,
                        Password = pwd1,
                        PasswordSalt = salt,
                        PasswordHash = passwordHash,
                        ObjectState = ObjectState.Added
                    };

                var newUser = new[]
                {
                    user1,
                    user2, user3
                };

                foreach (var user in newUser)
                {
                    try
                    {
                        userRepository.Insert(user);
                        unitOfWork.SaveChanges();
                    }
                    catch (DbEntityValidationException ex)
                    {
                        var sb = new StringBuilder();

                        foreach (var failure in ex.EntityValidationErrors)
                        {
                            sb.AppendFormat("{0} failed validation\n", failure.Entry.Entity.GetType());

                            foreach (var error in failure.ValidationErrors)
                            {
                                sb.AppendFormat("- {0} : {1}", error.PropertyName, error.ErrorMessage);
                                sb.AppendLine();
                            }
                        }

                        Debug.WriteLine(sb.ToString());
                        //TestContext.WriteLine(sb.ToString());
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(ex.Message);
                        //TestContext.WriteLine(ex.Message);
                    }
                }

                var insertedUser = userRepository.Query(x => x.FirstName == searchName).Select().FirstOrDefault();
                Assert.IsNotNull(insertedUser);
                Assert.IsTrue(insertedUser.FirstName == searchName);
            }
        }
    }
}
